<script setup lang="ts">
import type { IndicatorInfo } from '../type'
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
import { debounce } from 'lodash-es'
import Sortable from 'sortablejs'
import { indicatorApi, productionApi } from '~/api'
import { EFFICIENCY_DATA_TYPE, STORAGE_MODES } from './constant'
import IndicatorNumberPicker from './indicator-number-picker.vue'

const props = withDefaults(defineProps<{
  maxlength?: number
  location?: 0 | 1
  data?: {
    id: number
    title: string
    name: string
    location: 0 | 1
    indicatorNumber: string
    timeType: STORAGE_MODES
  }[]
}>(), {
  maxlength: 2,
  location: 0,
})
const emit = defineEmits<{
  (e: 'saveSuccess'): void
}>()
const sortRef = ref<HTMLDivElement>()
function uuid(prefix = '') {
  return prefix + (
    Date.now().toString(32)
    + Math.random().toString(32).substring(2)
  ).substring(2, 18)
}

const visible = defineModel<boolean>({ required: true })

const formRefs = ref<FormInstance[]>()

const title = ref()
const list = ref<{
  _uuid: string
  dataName: string
  dataValue: string
  dataType: EFFICIENCY_DATA_TYPE
  timeType?: STORAGE_MODES
  _timeTypeOptions: { label: string, value: string }[]
}[]>([])

const handleSave = debounce(_handleSave, 500)

const rules: FormRules = {
  dataName: [
    { required: true, message: '请输入数据名称', trigger: 'blur' },
  ],
  dataValue: [
    { required: true, message: '请选择指标编码', trigger: 'change' },
  ],
  timeType: [
    { required: true, message: '请选择数据周期', trigger: 'change' },
  ],
}

const formRules = ref<FormRules>()

async function handleAdd() {
  if (list.value.length < props.maxlength) {
    list.value.push({
      _uuid: uuid(),
      dataName: '',
      dataValue: '',
      dataType: EFFICIENCY_DATA_TYPE.INDICATOR,
      timeType: undefined,
      _timeTypeOptions: [],
    })
  }
  else {
    ElMessage.warning(`最多添加${props.maxlength}个数据`)
  }
}
async function handleRemove(item: any) {
  const index = list.value.indexOf(item)
  if (index > -1) {
    list.value.splice(index, 1)
  }
}

function handleChangeDataValue(indicator: IndicatorInfo, target: any) {
  const indicatorDataStoreCoreList = indicator?.indicatorDataStoreCoreList ?? []
  target._timeTypeOptions = indicatorDataStoreCoreList.map(v => ({
    label: getPeriodName(v.timeType),
    value: v.timeType,
  }))
  target.timeType = indicatorDataStoreCoreList[0].timeType
}

function getPeriodName(type: STORAGE_MODES) {
  switch (type) {
    case STORAGE_MODES.DAY:
      return '日'
    case STORAGE_MODES.MONTH:
      return '月'
    case STORAGE_MODES.YEAR:
      return '年'
    case STORAGE_MODES.NOW:
      return '实时'
    case STORAGE_MODES.FIFTEEN_MINUTES:
      return '15分钟'
    case STORAGE_MODES.HOUR:
      return '小时'
    default:
      return ''
  }
}

const sortInstance = ref<Sortable>()

function makeSortable() {
  if (sortInstance.value) {
    try {
      sortInstance.value.destroy?.()
    }
    catch {}
  }
  if (sortRef.value) {
    sortInstance.value = new Sortable(sortRef.value, {
      animation: 150,
      onEnd(evt) {
        const elem = evt.to
        try {
          const forms = Array.from(elem.querySelectorAll('form'))
          const ids: string[] = []
          for (const item of forms) {
            const id = item.getAttribute('data-key')
            if (id) {
              ids.push(id)
            }
          }
          const newList = []
          for (const id of ids) {
            const target = unref(list).find(v => v._uuid === id)
            if (target) {
              newList.push(target)
            }
          }
          list.value = newList
          triggerRef(list)
        }
        catch (e) {
          console.error(e)
        }
      },
    })
  }
}

async function validate() {
  const ret = []
  if (!formRefs.value)
    return []
  for (const formRef of formRefs.value) {
    const isOk = await formRef.validate().catch(() => false)
    ret.push(isOk)
  }
  return ret
}

async function _handleSave() {
  const res = await validate()
  if (res.includes(false))
    return false
  await productionApi.setConfig(props.location, title.value, list.value.map((v) => {
    return {
      location: props.location,
      name: v.dataName,
      indicatorNumber: v.dataValue,
      timeType: v.timeType!,
    }
  }))
  ElMessage.success('保存成功')
  visible.value = false
  emit('saveSuccess')
}

async function getPeriodList(indicatorNumber: string, item: any) {
  const { data } = await indicatorApi.queryIndicatorsByPage({
    pageNumber: 1,
    pageSize: 10,
    containSub: 1,
    keyword: indicatorNumber,
    pointId: 1,
  })
  const indicator = (data.records ?? []).find((v: any) => v.indicatorNumber === indicatorNumber)
  if (indicator) {
    const indicatorDataStoreCoreList = indicator?.indicatorDataStoreCoreList ?? []
    item._timeTypeOptions = indicatorDataStoreCoreList.map((v: any) => ({
      label: getPeriodName(v.timeType),
      value: v.timeType,
    }))
  }
  else {
    item._timeTypeOptions = []
  }
}

watch(list, () => {
  makeSortable()
}, { deep: true })

watch(visible, async (val) => {
  if (val) {
    formRules.value = undefined
    title.value = props.data?.[0]?.title
    list.value = props.data?.map((v) => {
      return {
        _uuid: uuid(),
        dataName: v.name,
        dataValue: v.indicatorNumber,
        dataType: EFFICIENCY_DATA_TYPE.INDICATOR,
        timeType: v.timeType,
        _timeTypeOptions: [],
      }
    }) ?? []
    triggerRef(list)
    for (const item of list.value) {
      getPeriodList(item.dataValue, item)
    }
    await nextTick()
    formRules.value = rules
  }
})

onMounted(async () => {
  await nextTick()
  makeSortable()
})
</script>

<template>
  <ElDrawer v-model="visible" class="custom-drawer" title="设置" :close-on-click-modal="false" :destroy-on-close="true" append-to="body" append-to-body resize>
    <div class="flex items-center p-3">
      <span class="required w-[80px] flex-shrink-0 opacity-80">标题：</span>
      <ElInput v-model.trim="title" class="!w-1/2" placeholder="请输入标题名称" :maxlength="10" />
      <ElButton class="ml-auto" type="success" @click="handleAdd">
        新增数据
      </ElButton>
    </div>
    <div>
      <div ref="sortRef">
        <ElForm v-for="item in list" ref="formRefs" :key="item._uuid" :model="item" :rules="formRules" :validate-on-rule-change="false" :data-key="item._uuid" label-width="80px" class="move-form relative pt-10">
          <ElFormItem label="数据名称" prop="dataName">
            <ElInput v-model.trim="item.dataName" placeholder="请输入数据名称" :maxlength="10" />
          </ElFormItem>
          <ElFormItem label="指标编码" prop="dataValue" for="abc">
            <IndicatorNumberPicker v-model="item.dataValue" :append-to="sortRef" @click-item="(indicator: IndicatorInfo) => handleChangeDataValue(indicator, item)" />
          </ElFormItem>
          <ElFormItem label="数据周期" prop="timeType">
            <ElSelect v-model="item.timeType" class="flex-auto" placeholder="请选择">
              <ElOption v-for="option in item._timeTypeOptions" :key="option.value" v-bind="option" />
            </ElSelect>
          </ElFormItem>
          <div class="absolute right-0 top-0">
            <ElTag type="danger" size="small" effect="dark" class="cursor-pointer" @click="handleRemove(item)">
              删除
            </ElTag>
          </div>
        </ElForm>
      </div>
    </div>
    <template #footer>
      <ElButton @click="visible = false">
        取消
      </ElButton>
      <ElButton type="success" @click="handleSave">
        确定
      </ElButton>
    </template>
  </ElDrawer>
</template>

<style scopeds>
.move-form .ep-form-item__label {
  cursor: move;
}
.required:before {
  content: '*';
  margin-right: 4px;
  color: rgb(254, 107, 107);
}
.chosenClass {
  border: solid 1px rgb(167, 20, 56);
}
</style>
